#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

# -------------------------------------------------------------------------- #
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             #
#                                                                            #
# Licensed under the Apache License, Version 2.0 (the "License"); you may    #
# not use this file except in compliance with the License. You may obtain    #
# a copy of the License at                                                   #
#                                                                            #
# http://www.apache.org/licenses/LICENSE-2.0                                 #
#                                                                            #
# Unless required by applicable law or agreed to in writing, software        #
# distributed under the License is distributed on an "AS IS" BASIS,          #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
# See the License for the specific language governing permissions and        #
# limitations under the License.                                             #
#--------------------------------------------------------------------------- # 

require 'vboxrc.rb'
require 'xml-parser.rb'

# Creates the VM with deployment params
def create
  c_args = create_args
  return nil unless c_args
  return run "#{VBOX_CREATE} #{c_args}"
end


# Unregister the Virtual Machine with deployment params
def unregister
  return run "#{VBOX_UNREGISTERVM} #{@vmname} --delete"
end


# Modifies Virtual Machine with deployment params
def modify
  m_args = modify_args
  return 0 unless m_args #no arguments, its ok
  return run "#{VBOX_MODIFYVM} #{m_args}"
end


# Deprecated VBOX 4.0
# Register mediums in VM
# def open_mediums
#   rc = 0
#   disk_number = 1
#   om_args = openmedium_args
#   return nil unless om_args
#   om_args.each do | args |
#     log "Executing... #{VBOX_OPENMEDIUM} #{args} \n\n"
#     log `#{VBOX_OPENMEDIUM} #{args}`
#     rc = $?.exitstatus
#     break if rc != 0
#   end
#   return rc
# end



#Cloning disks
def clone_disks
  rc = 0
  disk_locations.each do | disk_location |
    rc = run "#{File.dirname(__FILE__)}/cloneDisk.sh #{disk_location}"
    break if rc != 0
  end
  return rc
end


# Unregister mediums in VM with deployment params
def close_mediums
  rc = 0
  disk_number = 1
  cm_args = closemedium_args
  return nil unless cm_args
  cm_args.each do | args |
    rc = run "#{VBOX_CLOSEMEDIUM} #{args}"
    break if rc != 0
  end
  return rc
end


# Attaches storage controllers in VM with deployment params
def add_controllers
  rc = 0
  controllers = controllers_to_add
  return nil unless controllers

  controllers.each do | controller |
    rc = run "#{VBOX_STORAGECTL} #{@vmname} --name ONE-#{controller} --add #{controller}"
    break if rc != 0
  end
  return rc
end


# Atttach storage mediums in VM with deployment params
def storage_attach
  
  rc = 0
  storageattach_args.each do | sa_args |
    rc = run "#{VBOX_STORAGEATTACH} #{sa_args}"
    break if rc != 0
  end
  return rc
end

# Dettach storage devices with deployment params
def storage_dettach
  rc = 0
  storagedettach_args.each do | sd_args |
    rc = run "#{VBOX_STORAGEATTACH} #{sd_args}"
    break if rc != 0
  end
  return rc
end

# Start a virtual machine with deployment params
def start
  s_args = start_args
  return run "#{VBOX_STARTVM} #{@vmname} #{s_args}"
end


# VM info
def vminfo
  return run "#{VBOX_SHOWVMINFO} #{@vmname} --machinereadable"
end






#---------------------------CHANGING VM STATE-------------------#

# Power off the Virtual Machine
def power_off
  state = `#{VBOX_SHOWVMINFO} #{@vmname} | grep State`
  
  return 0 if state.include?("powered off")
  
  if state.include?("saved")
    return run "#{VBOX_DISCARDSTATE} #{@vmname}"
  end
  
  return run "#{VBOX_CONTROLVM} #{@vmname} poweroff"
end

# Powers off the Virtual Machine
# via the ACPI power button or the 
# standard way if ACPI is not supported
def power_off_acpi
  state = `#{VBOX_SHOWVMINFO} #{@vmname} | grep State`
  if supports_acpi? and state.include?("running")
    rc = run "#{VBOX_CONTROLVM} #{@vmname} acpipowerbutton"
  else
    rc = power_off
  end
  return rc
end

#checks if VM is powered off
def powered_off?
  rc = run %&#{VBOX_SHOWVMINFO} #{@vmname} | grep State | grep "powered off"&
  return true if rc == 0
  return nil
end

def pause
  return run "#{VBOX_CONTROLVM} #{@vmname} pause"
end

def snapshot_pause
  return run "#{VBOX_SNAPSHOT} #{@vmname} take one-snapshot --pause"
end

def save_state
  return run "#{VBOX_CONTROLVM} #{@vmname} savestate"
end

def adopt_state state_file
  return run "#{VBOX_ADOPTSTATE} #{@vmname} #{state_file}"
end

def get_uuid
  `#{VBOX_SHOWVMINFO} #{@vmname} | grep "^UUID" | cut -d':' -f2 | tr -d " "`.chomp
end

def run command
  log_message = "Executing #{command}\n\n"
  log_message += `#{command}`
  rc = $?.exitstatus
  log log_message,rc
  return rc
end

def log message,rc
  #if rc != 0 or DEBUG mode we log to stderr
  if rc != 0 or DEBUG
    $stderr.puts "ONE-VBOX: #{message}"
  end

  if DEBUG
    `echo 'ONE-VBOX: #{message}' >> #{DEBUG_LOG_FILE}`
  end
end


